package org.jspar.tile;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.util.List;

import org.jspar.model.Module;
import org.jspar.place.ModuleString;

public class SVGExporter {
	
	private static final int UNIT = 5;

	public static void export(String filename, Tile currentTile) {
		new SVGExporter().exportSVG(filename, currentTile);
	}
	
	public static void exportRoutingSpace(String filename, Tile hRoot, Tile vRoot) {
		new SVGExporter().exportRoutingSpaceSVG(filename, hRoot, vRoot);
	}

	private PrintStream str;
	
	private Rectangle computeBoundingBox(Rectangle r, Tile t) {
		for (Tile tile : t.allspace()) {
			if (r == null)
				r = tile.getBounds();
			else
				r = r.union(tile.getBounds());
		}
		return r;
	}
	
	private void start(String filename, Rectangle r) throws FileNotFoundException {
		str = new PrintStream(filename);
		str.println("<?xml version='1.0'?>");
		str.println("<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" ");
		str.println("\t\twidth=\""+r.width*UNIT+"\" height=\""+r.height*UNIT+"\" ");
		str.println("\t\tviewport=\""+r.x*UNIT+" "+r.y*UNIT+" "+(r.x+r.width)*UNIT+" "+ (r.y+r.height)*UNIT +"\">");
		
		str.println("<rect x=\"0\" y=\"0\" width=\"" + r.width*UNIT + "\" height=\""
				+ r.height*UNIT + "\" style=\"fill:white;stroke:none;\" />");
	}
	
	private void end() {
		str.println("</svg>");
		str.close();
	}
	
	private void exportTile(Tile tile, Rectangle r, String color, boolean transpose) {
		Rectangle re = new Rectangle((tile.x()-r.x)*UNIT, (tile.y()-r.y)*UNIT,
				tile.width()*UNIT, tile.height()*UNIT);
		if (transpose) {
			re = new Rectangle((tile.y()-r.y)*UNIT, (tile.x()-r.x)*UNIT,
					tile.height()*UNIT, tile.width()*UNIT);
		}
		str.println("<g>");
		str.println("<rect x=\"" + re.x + "\" y=\"" + re.y + "\" width=\"" + re.width + "\" height=\"" + re.height + "\"");
		if (tile.content() != null) {
			str.println("style=\"fill:green;stroke:"+color+";stroke-width:1;\" />");
			if (tile.content() instanceof ModuleString) {
				ModuleString string = (ModuleString) tile.content();
				for (Module m : string.modules()) {
					str.println("<g>");
					str.println("<rect x=\"" + (m.x()-r.x)*UNIT + "\" y=\"" + (m.y()-r.y)*UNIT + "\" width=\"" + m.width()*UNIT + "\" height=\""
							+ m.height()*UNIT + "\" style=\"fill:red;stroke:black;stroke-width:2;\" />");
					str.println("</g>");
				}
			}
		} else {
			str.println("style=\"fill:none;stroke:"+color+";stroke-width:2;\" />");
			str.println("<text x=\"" + (re.x + re.width / 2) + "\" y=\""
					+ (re.y + re.height / 2) + "\" style=\"text-anchor:middle;stroke:"+color+";\" >" + tile.id() + "</text>");
		}
		str.println("</g>");
	}
	
	public void exportSVG(String filename, Tile currentTile) {
		try {
			Rectangle r = computeBoundingBox(null, currentTile);;
			start(filename, r);
			
			for (Tile tile : currentTile.allspace()) {
				exportTile(tile, r, "black", false);
			}
			/*for(Module imod : partition.modules()) {
				for(Terminal jterm : imod.terminals()) {
					for(Terminal kterm : jterm.net().terminals()) {
						Module m = kterm.module();
						if(imod != m
								&& m.hasFlag(Module.PLACED)
								&& m.partition() == partition) {
							str.println("<line x1=\""+(jterm.globalX()-minX)*UNIT + "\" y1=\""+(jterm.globalY()-minY)*UNIT
									+"\" x2=\""+(kterm.globalX()-minX)*UNIT+"\" y2=\""+(kterm.globalY()-minY)*UNIT
									+"\" style=\"stroke:blue;stroke-width:1\"/>");
						}
					}
				}
			}*/
			end();
			
		} catch (IOException e) {
		}
	}

	public void exportRoutingSpaceSVG(String filename, Tile hRoot, Tile vRoot) {
		try {
			Rectangle r = computeBoundingBox(null, hRoot);
			start(filename, r);
			
			for (Tile tile : hRoot.allspace()) {
				exportTile(tile, r, "black", false);
			}
			for (Tile tile : vRoot.allspace()) {
				exportTile(tile, r, "red", true);
			}
			end();
			
		} catch (IOException e) {
		}
	}

}
